package com.xiaoma.tpo.webservice;

import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.xiaoma.tpo.domain.ForumPost;
import com.xiaoma.tpo.domain.ForumTopic;
import com.xiaoma.tpo.domain.ForumTopicStore;
import com.xiaoma.tpo.domain.ForumUserWatch;
import com.xiaoma.tpo.domain.User;
import com.xiaoma.tpo.dto.ForumPaginateDto;
import com.xiaoma.tpo.dto.ForumPostDto;
import com.xiaoma.tpo.dto.ForumTopicDto;
import com.xiaoma.tpo.dto.TeacherVo;
import com.xiaoma.tpo.dto.TopicSum;
import com.xiaoma.tpo.resource.TPOConstants;
import com.xiaoma.tpo.service.ForumService;
import com.xiaoma.tpo.service.UserService;
import com.xiaoma.tpo.utils.Pager;
import com.xiaoma.tpo.utils.TPOUtils;

@Controller
@RequestMapping("/service/forum")
public class ForumWS {

    private static Logger LOG = LoggerFactory.getLogger(ForumWS.class);
    
    @Autowired
    private ForumService forumService;
    
    @Autowired
    private UserService userService;
    
    @RequestMapping(value = "/topic" ,method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> createTopic(@RequestHeader String token, @RequestBody ForumTopicDto topicDto){
        Map<String, Object> result = new HashMap<String, Object>();
        User user = userService.findByToken(token);
        if(null == user) {
            result.put("status", -2);
            result.put("message", "invalid token");
            return result;
        }
        if (TPOUtils.isAnonymous(user)) {
            result.put("status", 0);
            result.put("message", "anonymous can't access");
            return result;
            
        }
        Date now = new Date();
        if (TPOUtils.over7days(now, user.getLastVisit())) {//大于7天token失效
            result.put("status", -1);
            result.put("message", "token disabled over 7 days, please login");
            return result;
        }
        try {
            JSONArray ja = new JSONArray();
            List<String> imgs = topicDto.getImgs();
            for (int i = 0; i < imgs.size(); i++) {
                String path = imgs.get(i);
                ja.add(path);
            }
            ForumTopic topic = new ForumTopic();
            topic.setTitle(topicDto.getTitle());
            topic.setContent(topicDto.getContent());
            if (!ja.isEmpty()) {
                topic.setImgs(ja.toString());
            }
            topic.setUserId(user.getId());
            topic.setCreatedAt(now);
            topic.setUpdatedAt(now);
            forumService.saveForumTopic(topic);
            
            Pager pager  = forumService.findTopics(0, 20);
            result.put("records", pager.getList());
            result.put("totalCount", pager.getTotalCount());
            userService.updateVisitTime(user);
        } catch(Exception e) {
            result.put("status", 0);
            result.put("message", e);
        }
        return result;
        
    }
    
    
    @RequestMapping(value = "/topics" ,method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> findTopics(@RequestHeader String token, Integer topicId, Integer itemsPerPage) {
        Map<String, Object> result = new HashMap<String, Object>();
        User user = userService.findByToken(token);
        if(null == user) {
            result.put("status", -2);
            result.put("message", "invalid token");
            return result;
        }
        if (TPOUtils.isAnonymous(user)) {
            result.put("status", 0);
            result.put("message", "anonymous can't access");
            return result;
            
        }
        if (TPOUtils.over7days(new Date(), user.getLastVisit())) {//大于7天token失效
            result.put("status", -1);
            result.put("message", "token disabled over 7 days, please login");
            return result;
        }
        if (topicId == 0) {
            Pager pager  = forumService.findTopics(0, itemsPerPage);
            result.put("records", pager.getList());
            result.put("totalCount", pager.getTotalCount());
        } else {
            result.put("records", forumService.findOldTopics(topicId, itemsPerPage));
            ForumTopic entity = new ForumTopic();
            result.put("totalCount", forumService.getTopicCount(entity));
        }
        userService.updateVisitTime(user);
        return result;
    }
    
    @RequestMapping(value = "/topics/type/{type}" ,method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> findTopics(@RequestHeader String token, @PathVariable Integer type, Integer topicId, Integer itemsPerPage) {
        Map<String, Object> result = new HashMap<String, Object>();
        User user = userService.findByToken(token);
        if(null == user) {
            result.put("status", -2);
            result.put("message", "invalid token");
            return result;
        }
        if (TPOUtils.isAnonymous(user)) {
            result.put("status", 0);
            result.put("message", "anonymous can't access");
            return result;
            
        }
        if (TPOUtils.over7days(new Date(), user.getLastVisit())) {//大于7天token失效
            result.put("status", -1);
            result.put("message", "token disabled over 7 days, please login");
            return result;
        }
        if (topicId == 0) {
            Pager pager  = forumService.findTopics(0, itemsPerPage, type);
            result.put("records", pager.getList());
            result.put("totalCount", pager.getTotalCount());
        } else {
            result.put("records", forumService.findOldTopics(topicId, itemsPerPage, type));
            ForumTopic entity = new ForumTopic();
            entity.setType(type);
            result.put("totalCount", forumService.getTopicCount(entity));
        }
        userService.updateVisitTime(user);
        return result;
    }
    
    @RequestMapping(value = "/topics/{topicId}/posts" ,method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> findPosts(@RequestHeader String token, @PathVariable Integer topicId, ForumPaginateDto pageDto) {
        Map<String, Object> result = new HashMap<String, Object>();
        User user = userService.findByToken(token);
        if(null == user) {
            result.put("status", -2);
            result.put("message", "invalid token");
            return result;
        }
        if (TPOUtils.isAnonymous(user)) {
            result.put("status", 0);
            result.put("message", "anonymous can't access");
            return result;
            
        }
        if (TPOUtils.over7days(new Date(), user.getLastVisit())) {//大于7天token失效
            result.put("status", -1);
            result.put("message", "token disabled over 7 days, please login");
            return result;
        }
        Pager pager = forumService.findPostsByTopicId(topicId,(pageDto.getPage() - 1) * pageDto.getItemsPerPage(), pageDto.getItemsPerPage());
        result.put("records", pager.getList());
        result.put("totalCount", pager.getTotalCount());
        ForumTopic topic = forumService.getTopicById(topicId);
        if (topic != null) {
            topic.setReadCount(topic.getReadCount() + 1);
            forumService.updateForumTopic(topic);
        }
        ForumTopicStore topicStore = forumService.findTopicStore(user.getId(), topicId);
        if (topicStore != null) {
            result.put("stored", true);
        } else {
            result.put("stored", false);
        }
        userService.updateVisitTime(user);
        return result;
    }
    
    @RequestMapping(value = "/posts/{postId}/children", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> findChildPosts(@RequestHeader String token, @PathVariable Integer postId, ForumPaginateDto pageDto) {
        Map<String, Object> result = new HashMap<String, Object>();
        User user = userService.findByToken(token);
        if(null == user) {
            result.put("status", -2);
            result.put("message", "invalid token");
            return result;
        }
        if (TPOUtils.isAnonymous(user)) {
            result.put("status", 0);
            result.put("message", "anonymous can't access");
            return result;
            
        }
        if (TPOUtils.over7days(new Date(), user.getLastVisit())) {//大于7天token失效
            result.put("status", -1);
            result.put("message", "token disabled over 7 days, please login");
            return result;
        }
        Pager pager = forumService.findPostChildren(postId,(pageDto.getPage() - 1) * pageDto.getItemsPerPage(), pageDto.getItemsPerPage());
        result.put("records", pager.getList());
        result.put("totalCount", pager.getTotalCount());
        userService.updateVisitTime(user);
        return result;
    }
    
    
    @RequestMapping(value = "/post" ,method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> savePost(@RequestHeader String token, @RequestBody ForumPostDto postDto) {
        Map<String, Object> result = new HashMap<String, Object>();
        User user = userService.findByToken(token);
        if(null == user) {
            result.put("status", -2);
            result.put("message", "invalid token");
            return result;
        }
        if (TPOUtils.isAnonymous(user)) {
            result.put("status", 0);
            result.put("message", "anonymous can't access");
            return result;
            
        }
        Date now = new Date();
        if (TPOUtils.over7days(now, user.getLastVisit())) {//大于7天token失效
            result.put("status", -1);
            result.put("message", "token disabled over 7 days, please login");
            return result;
        }
        ForumTopic topic = forumService.getTopicById(postDto.getTopicId());
        if (topic == null) {
            result.put("status", 0);
            result.put("message", "invalid topicId " + postDto.getTopicId());
        } else {
            try {
                JSONArray ja = new JSONArray();
                List<String> imgs = postDto.getImgs();
                for (int i = 0; i < imgs.size(); i++) {
                    ja.add(imgs.get(i));
                }
                ForumPost post = new ForumPost();
                post.setUserId(user.getId());
                post.setCreatedAt(now);
                post.setTopicId(postDto.getTopicId());
                post.setParentId(postDto.getParentId());
                post.setContent(postDto.getContent());
                if (!ja.isEmpty()) {
                    post.setImgs(ja.toString());
                }
                if (topic.getUserId().equals(user.getId())) {
                    post.setOwner(true);
                }
                forumService.savePost(post);
                topic.setPostCount(topic.getPostCount() + 1);
                forumService.updateForumTopic(topic);
                Pager pager = null;
                if (post.getParentId() == 0) {
                    pager =  forumService.findPostsByTopicId(topic.getId(), 0, 20);
                } else {
                    pager = forumService.findPostChildren(post.getParentId(), 0, 20);
                }
                result.put("records", pager.getList());
                result.put("totalCount", pager.getTotalCount());
                userService.updateVisitTime(user);
            } catch(Exception e) {
                result.put("status", 0);
                result.put("message", e);
            }
        }
        return result;
    }
    
    
    @RequestMapping(value = "/topics/{topicId}/top" ,method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> toTop(@RequestHeader String token, @PathVariable Integer topicId) {
        Map<String, Object> result = new HashMap<String, Object>();
        User user = userService.findByToken(token);
        if(null == user) {
            result.put("status", -2);
            result.put("message", "invalid token");
            return result;
        }
        if (TPOUtils.isAnonymous(user)) {
            result.put("status", 0);
            result.put("message", "anonymous can't access");
            return result;
            
        }
        if (TPOUtils.over7days(new Date(), user.getLastVisit())) {//大于7天token失效
            result.put("status", -1);
            result.put("message", "token disabled over 7 days, please login");
            return result;
        }
        forumService.toTop(topicId);
        Pager pager  =  forumService.findTopics(0,20);
        result.put("records", pager.getList());
        result.put("totalCount", pager.getTotalCount());
        userService.updateVisitTime(user);
        return result;
    }
    
    @RequestMapping(value = "/topics/{topicId}/share" ,method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> share(@PathVariable Integer topicId) {
        Map<String, Object> result = new HashMap<String, Object>();
        ForumTopic topic = forumService.getTopicById(topicId);
        if (topic != null) {
            topic.setShareCount(topic.getShareCount() + 1);
            forumService.updateForumTopic(topic);
        }
        result.put("status", 1);
        return result;
    }
    
    @RequestMapping(value = "/topics/{topicId}/store" ,method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> store(@RequestHeader String token, @PathVariable Integer topicId) {
        Map<String, Object> result = new HashMap<String, Object>();
        User user = userService.findByToken(token);
        if(null == user) {
            result.put("status", -2);
            result.put("message", "invalid token");
            return result;
        }
        ForumTopicStore topicStore = forumService.findTopicStore(user.getId(), topicId);
        if (topicStore == null) {
            topicStore = new ForumTopicStore();
            topicStore.setTopicId(topicId);
            topicStore.setUserId(user.getId());
            forumService.saveStore(topicStore);
            ForumTopic topic = forumService.getTopicById(topicId);
            if (topic != null) {
                topic.setStoreCount(topic.getStoreCount() + 1);
                forumService.updateForumTopic(topic);
            }
        }
        userService.updateVisitTime(user);
        result.put("status", 1);
        return result;
    }
    
    @RequestMapping(value = "/topics/{topicId}/cancelStore" ,method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> cancelStore(@RequestHeader String token, @PathVariable Integer topicId) {
        Map<String, Object> result = new HashMap<String, Object>();
        User user = userService.findByToken(token);
        if(null == user) {
            result.put("status", -2);
            result.put("message", "invalid token");
            return result;
        }
        int n = forumService.deleteStore(user.getId(), topicId);
        if (n > 0) {
            ForumTopic topic = forumService.getTopicById(topicId);
            if (topic != null) {
                topic.setStoreCount(topic.getStoreCount() - 1);
                forumService.updateForumTopic(topic);
            }
        }
        userService.updateVisitTime(user);
        result.put("status", 1);
        return result;
    }
    
    @RequestMapping(value = "/topics/myStore" ,method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> myStore(@RequestHeader String token) {
        Map<String, Object> result = new HashMap<String, Object>();
        User user = userService.findByToken(token);
        if(null == user) {
            result.put("status", -2);
            result.put("message", "invalid token");
            return result;
        }
        result.put("topics", forumService.findStoredTopics(user.getId()));
        return result;
    }
    
    @RequestMapping(value = "/watch/{teacherId}" ,method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> watch(@RequestHeader String token, @PathVariable Integer teacherId) {
        Map<String, Object> result = new HashMap<String, Object>();
        User user = userService.findByToken(token);
        if(null == user) {
            result.put("status", -2);
            result.put("message", "invalid token");
            return result;
        }
        if (user.getId().intValue() != teacherId) {
            ForumUserWatch userWatch = forumService.findUserWatch(user.getId(), teacherId);
            if (userWatch == null) {
                userWatch = new ForumUserWatch();
                userWatch.setUserId(user.getId());
                userWatch.setTeacherId(teacherId);
                forumService.saveWatch(userWatch);
            }
            result.put("status", 1);
        } else {
            result.put("status", 0);
            result.put("message", "can't watch oneself");
        }
        return result;
    }
    
    @RequestMapping(value = "/teacherInfo/{teacherId}" ,method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> teacherInfo(@RequestHeader String token, @PathVariable Integer teacherId) {
        Map<String, Object> result = new HashMap<String, Object>();
        TeacherVo teacher = userService.findTeacherById(teacherId);
        if (teacher != null) {
            result.put("teacher", teacher);
            User user = userService.findByToken(token);
            if (user != null) {
                ForumUserWatch userWatch = forumService.findUserWatch(user.getId(), teacherId);
                if (userWatch != null) {
                    result.put("watched", true);
                } else {
                    result.put("watched", false);
                }
            }
            TopicSum topicSum = forumService.topicSum(teacherId);
            if (topicSum != null) {
                result.put("readTotal", topicSum.getReadTotal());
                result.put("shareTotal", topicSum.getShareTotal());
                result.put("storeTotal", topicSum.getStoreTotal());
            }
            result.put("fansTotal", forumService.watchCount(teacherId));
            ForumTopic entity = new ForumTopic();
            entity.setUserId(teacherId);
            result.put("topics", forumService.findTopics(teacherId));
        } else {
            result.put("status", 0);
            result.put("message", "can't find teacher with id = " + teacherId);
        }
        return result;
    }
    
    @RequestMapping(value = "/feedback" ,method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> feedback(@RequestHeader String token) {
        Map<String, Object> result = new HashMap<String, Object>();
        User user = userService.findByToken(token);
        if(null == user) {
            result.put("status", -2);
            result.put("message", "invalid token");
            return result;
        }
        result.put("records", forumService.findFeedbackTopics(user.getId()));
        return result;
    }
    
    public static void main(String args[]) {
        JSONObject jb = new JSONObject();
        jb.put(1, "aaaaaa");
        jb.put(2, "bbbbbb");
        String s = jb.toString();
        JSONArray ja = new JSONArray();
        ja.add("xxxx");
        ja.add("yyyy");
        System.out.println(s);
        System.out.println(ja.toString());
        String[] ss = {"aaa","bbb"};
        System.out.println(Arrays.toString(ss));
        System.out.println(ss.toString());
        
    }
    
}
